package com.michael.ims.gateway.webfilter;

import com.michael.common.utils.TokenProcessor;
import com.michael.ims.gateway.common.util.matcher.PathPatternParserServerWebExchangeMatcher;
import com.michael.ims.gateway.common.util.matcher.ServerWebExchangeMatcher;
import com.michael.io.UserInfo;
import org.springframework.core.annotation.Order;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

import static com.michael.ims.gateway.config.SystemConfig.CONTEXT_PATH;


/**
 * 校验Token的
 * 有效性
 */
@Order(300)
@Component
public class TokenValidatorWebFilter implements WebFilter {
    private final static ServerWebExchangeMatcher matcherApi = new PathPatternParserServerWebExchangeMatcher(CONTEXT_PATH + "/**");
    private final static ServerWebExchangeMatcher matcherLogin = new PathPatternParserServerWebExchangeMatcher(CONTEXT_PATH + "/login");

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        return matcherApi.matches(exchange)
                .flatMap(apiMatch -> {
                    if (apiMatch.isMatch()) {
                        return matcherLogin.matches(exchange)
                                .flatMap(loginMatch -> {
                                    if (loginMatch.isMatch()) {
                                        return chain.filter(exchange);
                                    } else {
                                        //校验token
                                        ServerHttpRequest request = exchange.getRequest();
                                        String token = request.getHeaders().getFirst("token");

                                        UserInfo userInfo = TokenProcessor.decode(token);
                                        exchange.getAttributes().put("userInfo", userInfo);

                                        //覆盖其token的内容
                                        String newToken = TokenProcessor.encodeOther(2, userInfo);
                                        ServerHttpRequest newRequest = exchange.getRequest().mutate()
                                                .headers(httpHeaders -> httpHeaders.set("token", newToken))
                                                .build();

                                        return chain.filter(exchange.mutate().request(request).build());
                                    }
                                });
                    } else {
                        return chain.filter(exchange);
                    }
                });
    }

}
